package sessionBeans;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import entityBeans.Address;
import entityBeans.Contact;
import entityBeans.ContactGroup;
import entityBeans.Enterprise;
import entityBeans.PhoneNumber;

@Stateless(mappedName = "ContactBeanEntity")
public class GestionContactBeanEntity implements GestionContactLocal {
	@PersistenceContext
	EntityManager em;

	@Override
	public Contact addContact(Contact c) {
		em.persist(c);
		return c;
	}

	@Override
	public void delete(int id) {
		Query q = em
				.createNativeQuery("DELETE FROM contactgroup_contact WHERE contacts_id = :id");
		q.setParameter("id", id);
		q.executeUpdate();
		Contact c = em.find(Contact.class, id);
		em.remove(c);
	}

	@Override
	public List<Contact> searchByName(String name) {
		Query query = em
				.createQuery("SELECT OBJECT(c) FROM Contact AS c where c.firstName LIKE?1");
		query.setParameter(1, name);
		List<Contact> listContact = (List<Contact>) query.getResultList();
		return listContact;
	}

	@Override
	public List<Contact> searchByEmail(String email) {
		Query query = em
				.createQuery("SELECT OBJECT(c) FROM Contact AS c where c.email LIKE?1");
		query.setParameter(1, email);
		List<Contact> listContact = (List<Contact>) query.getResultList();
		return listContact;
	}

	@Override
	public Contact searchById(int id) {
		Query query = em
				.createQuery("SELECT c FROM Contact c where c.id = :id");
		query.setParameter("id", id);
		Contact contact = (Contact) query.getSingleResult();
		return contact;
	}

	public Enterprise searchEntById(int id) {
		Query query = em
				.createQuery("SELECT c FROM Enterprise c where c.id = :id");
		query.setParameter("id", id);
		Enterprise contact = (Enterprise) query.getSingleResult();
		return contact;
	}

	@Override
	public void updateContact(Contact contact, List<String> groups) {
		Contact cg;
		if (contact instanceof Contact)
			cg = em.find(Contact.class, contact.getId());
		else
			cg = em.find(Enterprise.class, contact.getId());
		Address addr = em.find(Address.class, cg.getAddress().getIdAddress());

		// phones
		List<PhoneNumber> phones = (List<PhoneNumber>) em
				.createQuery(
						"select p from PhoneNumber p where p.contact = :contact")
				.setParameter("contact", cg).getResultList();

		for (int i = 0; i < contact.getPhones().size(); i++) {
			phones.get(i).setPhoneKind(
					((PhoneNumber) (contact.getPhones().toArray()[i]))
							.getPhoneKind());
			phones.get(i).setPhoneNumber(
					((PhoneNumber) (contact.getPhones().toArray()[i]))
							.getPhoneNumber());
		}

		// address
		addr.setCity(contact.getAddress().getCity());
		addr.setCountry(contact.getAddress().getCountry());
		addr.setZip(contact.getAddress().getZip());
		addr.setStreet(contact.getAddress().getStreet());

		// groups
		Query q = em
				.createNativeQuery("DELETE FROM contactgroup_contact WHERE contacts_id = :id");
		q.setParameter("id", cg.getId());
		q.executeUpdate();

		for (String name : groups) {
			Query query = em
					.createQuery("select g from ContactGroup g where g.groupName= :gname");
			query.setParameter("gname", name);
			ContactGroup group = (ContactGroup) query.getSingleResult();
			group.getContacts().add(cg);
			cg.getBooks().add(group);
		}

		cg.setEmail(contact.getEmail());
		cg.setLastName(contact.getLastName());
		cg.setFirstName(contact.getFirstName());

		// siret if enterprise
		if (contact instanceof Enterprise)
			((Enterprise) cg).setNumSiret(((Enterprise) contact).getNumSiret());
		em.flush();

	}

	@Override
	public void updateEnterprise(Enterprise ent) {
		// TODO Auto-generated method stub

	}

	@Override
	public List<Contact> search() {

		Query query = em.createQuery("SELECT c FROM Contact c");
		List<Contact> listContact = (List<Contact>) query.getResultList();
		List<Contact> res = new ArrayList<Contact>();
		for (Contact contact : listContact) {
			if (!(contact instanceof Enterprise))
				res.add(contact);
		}
		return res;
	}

	@Override
	public List<Contact> searchByGroupID(String idGrp) {
		Query q = em
				.createQuery("select distinct c from Contact c inner join c.books g where g.groupName = :id");
		q.setParameter("id", idGrp);
		List<Contact> contacts = (List<Contact>) q.getResultList();
		return contacts.size() == 0 ? null : contacts;
	}

	@Override
	public List<Enterprise> searchEnt() {

		List<Enterprise> entreprises = new ArrayList<Enterprise>();
		Query query = em.createQuery("SELECT c FROM Contact c");
		List<Contact> listContact = (List<Contact>) query.getResultList();

		for (Contact contact : listContact) {
			if (contact instanceof Enterprise)
				entreprises.add((Enterprise) contact);
		}
		return entreprises;
	}

	@Override
	public ContactGroup find(String name) {
		Query query = em
				.createQuery("SELECT OBJECT(c) FROM ContactGroup c WHERE c.groupName = :name");
		query.setParameter("name", name);
		return (ContactGroup) query.getSingleResult();
	}

}
